#include "cpu/exec/template-start.h"
#include "cpu/reg.h"
#define instr mov

static void do_execute() {
	OPERAND_W(op_dest, op_src->val);
	print_asm_template2();
}

make_instr_helper(i2r)
make_instr_helper(i2rm)
make_instr_helper(r2rm)
make_instr_helper(rm2r)

make_helper(concat(mov_a2moffs_, SUFFIX)) {
	swaddr_t addr = instr_fetch(eip + 1, 4);
	MEM_W(addr, REG(R_EAX), R_DS);

	print_asm("mov" str(SUFFIX) " %%%s,0x%x", REG_NAME(R_EAX), addr);
	return 5;
}

make_helper(concat(mov_moffs2a_, SUFFIX)) {
	swaddr_t addr = instr_fetch(eip + 1, 4);
	REG(R_EAX) = MEM_R(addr, R_DS);

	print_asm("mov" str(SUFFIX) " 0x%x,%%%s", addr, REG_NAME(R_EAX));
	return 5;
}

//以下为PA3内容
#if DATA_BYTE == 4

make_helper(mov_cr2r) {
    uint8_t modrm = instr_fetch(eip + 1, 1);
    int cr  = (modrm >> 3) & 0x7; //控制寄存器索引 
    int rm  = modrm & 0x7;        //通用寄存器索引
    uint32_t val;
    switch (cr) {
        case 0: val = cpu.cr0.val; break;
        //case 3: val = cpu.cr3.val; break;
        default: assert(0); break;
    }
    reg_l(rm) = val;
    // if (cr == 3) {
    //     int i;
    //     for (i = 0; i < TLB_SIZE; i++) tlb[i].valid = false;
    // }
    print_asm("mov %%cr%d,%%%s", cr, REG_NAME(rm));
    return 2;
}

make_helper(mov_r2cr) {
    uint8_t modrm = instr_fetch(eip + 1, 1);
    int cr  = (modrm >> 3) & 0x7;
    int rm  = modrm & 0x7;
    uint32_t val = reg_l(rm);
    switch (cr) {
        case 0: cpu.cr0.val = val; break;
        //case 3: cpu.cr3.val = val; break;
        default: assert(0); break;
    }

    // if (cr == 3) {
    //     int i;
    //     for (i = 0; i < TLB_SIZE; i++) tlb[i].valid = false;
    // }

    print_asm("mov %%%s,%%cr%d", REG_NAME(rm), cr);
    return 2;
}
#endif
#if DATA_BYTE == 2
make_helper(mov_rm2sreg) {
    uint8_t modrm = instr_fetch(eip + 1, 1);
    int sreg = (modrm >> 3) & 0x7; //段寄存器索引
    int rm   = modrm & 0x7;        //通用寄存器索引
    uint16_t val = reg_w(rm);
    //IA-32 不允许用 mov 指令设置 CS 
    if (sreg == 1) {
        assert(0);
    }
    sreg_load(sreg, val);
    print_asm("mov %%%s,%%sreg%d", REG_NAME(rm), sreg);
    return 2;
}
#endif
#include "cpu/exec/template-end.h"
